#include <iostream>
#include <memory>
#include <string>
#include <functional>
#include "ThreadPoll.hpp"
#include "Socket.hpp"
#include "Protocol.hpp"
#include "Log.hpp"
#include "NetCal.hpp"

namespace ApplicationServerModule
{
    using Handler = std::function<void(uint16_t, std::string)>;
    using namespace SocketModule;
    using namespace LogModule;
    using namespace ThreadPollModule;
    using namespace ProtocolModule;
    const static uint16_t defaultport = 8889;
    const static std::string defaultip = "0.0.0.0";

    class ApplicationServer
    {

    public:
        ApplicationServer(uint16_t port = defaultport, std::string ip = defaultip)
            : _socket(std::make_shared<TcpSocket>()), _port(port), _ip(ip)
        {
            _socket->CreateTcpSocket(_port, _ip);
        }

        void Start()
        {
            while (true)
            {
                std::string ip;
                uint16_t port;
                std::shared_ptr<Socket> sock = _socket->AcceptConnect(&port, &ip);
                using func_t = std::function<void()>;
                func_t in = std::bind(&ApplicationServer::Service, this, port, ip, sock);
                // 1. 取单例
                ThreadPoll *tp = ThreadPoll::GetInstance();

                // 2. 启动线程池
                tp->Start();
                tp->Enqueue(in);
            }
        }

        void Service(uint16_t port, std::string ip, std::shared_ptr<Socket> sock)
        {
            std::string msg;
            while (true)
            {
                LOG(LogLevel::DEBUG) << sock->GetSocket();
                // 1、读取消息
                if (sock->ReadMessage(&msg))
                {
                    std::string IntactMsg;
                    // 2、提取消息
                    if (Decode(msg, &IntactMsg))
                    {
                        LOG(LogLevel::INFO) << "server receive message form client : (json)" << IntactMsg;
                        // 3、将json串改成结构化数据
                        ProtocolModule::Request req;
                        req.Deserialize(IntactMsg);
                        // 4、计算结果
                        ProtocolModule::Response res = Cal().Execute(req);
                        // 5、序列化结果
                        std::string ans;
                        res.Serialize(&ans);
                        // 6、格式化消息
                        ans = ProtocolModule::Encode(ans);
                        // 7、发送消息到客户端
                        sock->WriteMessage(&ans);
                        LOG(LogLevel::INFO) << "server send message to client : (json)" << ans;
                    }
                }
                // 设置退出功能
                // to do
            }
        }

    private:
        std::shared_ptr<Socket> _socket;
        uint16_t _port;
        std::string _ip;
        Handler _handler; // 进程池的回调
    };
}